home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / BBS-Archive / Comm / term-source.lha / Extras / Source / term-Source.lha / termReviewBuffer.c < prev    next >
C/C++ Source or Header  |  1995-06-17  |  37KB  |  1,843 lines

  1. /*
  2. **    termReviewBuffer.c
  3. **
  4. **    Support routines for the review buffer
  5. **
  6. **    Copyright © 1990-1995 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12.     /* Handy signal masks. */
  13.  
  14. #define SIG_REVIEWPORT        (1L << ReviewPort -> mp_SigBit)
  15. #define SIG_REVIEWWINDOW    (1L << ReviewWindow -> UserPort -> mp_SigBit)
  16.  
  17.     /* Menu item codes. */
  18.  
  19. enum    {    MEN_SEARCH,MEN_REPEAT,MEN_CLEARBUF,MEN_QUITBUF };
  20.  
  21.     /* Gadget ID codes. */
  22.  
  23. enum    {    GAD_SCROLLER, GAD_UP, GAD_DOWN };
  24.  
  25. STATIC struct NewMenu ReviewMenu[] =
  26. {
  27.     { NM_TITLE, NULL,         0 , 0, 0, (APTR)0},
  28.     {  NM_ITEM, NULL,         0 , 0, 0, (APTR)MEN_SEARCH},
  29.     {  NM_ITEM, NULL,         0 , 0, 0, (APTR)MEN_REPEAT},
  30.     {  NM_ITEM, NM_BARLABEL,     0 , 0, 0, (APTR)0},
  31.     {  NM_ITEM, NULL,         0 , 0, 0, (APTR)MEN_CLEARBUF},
  32.     {  NM_ITEM, NM_BARLABEL,     0 , 0, 0, (APTR)0},
  33.     {  NM_ITEM, NULL,         0 , 0, 0, (APTR)MEN_QUITBUF},
  34.  
  35.     { NM_END, 0,             0 , 0, 0, (APTR)0}
  36. };
  37.  
  38.     /* Local routines. */
  39.  
  40. STATIC VOID        ReviewUpdatePot(VOID);
  41. STATIC VOID __stdargs    ReviewWrites(STRPTR String,...);
  42. STATIC VOID __regargs     PrintReviewLine(STRPTR Buffer,LONG Line);
  43. STATIC VOID __regargs     RefreshReview(LONG Top);
  44. STATIC VOID __regargs    ScrollReview(LONG Top);
  45. STATIC BYTE        ReviewQuery(VOID);
  46. STATIC UBYTE __regargs    GetReviewChar(BYTE WaitForIt);
  47.  
  48.     /* Local variables. */
  49.  
  50. STATIC struct Menu        *ReviewMenuStrip;
  51.  
  52. STATIC struct IBox         ReviewBox = { -1 };
  53. STATIC struct IOStdReq        *ReviewWriteRequest,
  54.                 *ReviewReadRequest;
  55.  
  56. STATIC struct MsgPort        *ReviewPort,
  57.                 *ReviewWritePort;
  58.  
  59. STATIC struct Gadget        *Scroller,
  60.                 *UpArrow,
  61.                 *DownArrow;
  62.  
  63. STATIC UWORD             RightBorderWidth;
  64.  
  65. STATIC struct Image        *UpImage,
  66.                 *DownImage;
  67.  
  68. STATIC UBYTE             ReviewChar;
  69. STATIC LONG             ReviewColumns,ReviewLines,
  70.                  ReviewTop = -1,ReviewGlobalLines;
  71.  
  72. STATIC BYTE             SearchForward    = TRUE,
  73.                  IgnoreCase    = TRUE,
  74.                  WholeWords    = FALSE;
  75.  
  76. STATIC UBYTE            *ReviewLineWidths;
  77. STATIC LONG             ReviewMaxLines;
  78.  
  79. STATIC struct MsgQueue        *ReviewQueue;
  80. STATIC struct Process        *ReviewProcess;
  81.  
  82. STATIC WORD             ReviewPen;
  83. STATIC BYTE             ReviewSignal;
  84.  
  85. STATIC struct TextFont        *LocalFont;
  86. STATIC struct TTextAttr         LocalTextFont;
  87. STATIC UBYTE __far         LocalTextFontName[MAX_FILENAME_LENGTH];
  88.  
  89.     /* ReviewDeleteScroller(VOID):
  90.      *
  91.      *    Delete scroller and arrow buttons.
  92.      */
  93.  
  94. STATIC VOID
  95. ReviewDeleteScroller(VOID)
  96. {
  97.     if(Scroller)
  98.     {
  99.         DisposeObject(Scroller);
  100.  
  101.         Scroller = NULL;
  102.     }
  103.  
  104.     if(UpArrow)
  105.     {
  106.         DisposeObject(UpArrow);
  107.  
  108.         UpArrow = NULL;
  109.     }
  110.  
  111.     if(DownArrow)
  112.     {
  113.         DisposeObject(DownArrow);
  114.  
  115.         DownArrow = NULL;
  116.     }
  117.  
  118.     if(UpImage)
  119.     {
  120.         DisposeObject(UpImage);
  121.  
  122.         UpImage = NULL;
  123.     }
  124.  
  125.     if(DownImage)
  126.     {
  127.         DisposeObject(DownImage);
  128.  
  129.         DownImage = NULL;
  130.     }
  131. }
  132.  
  133.     /* ReviewCreateScroller(struct Screen *Screen):
  134.      *
  135.      *    Create scroller and arrow buttons.
  136.      */
  137.  
  138. STATIC BYTE __regargs
  139. ReviewCreateScroller(struct Screen *Screen)
  140. {
  141.     struct DrawInfo    *DrawInfo;
  142.     BYTE         Result = FALSE;
  143.  
  144.     if(DrawInfo = GetScreenDrawInfo(Screen))
  145.     {
  146.         struct Image    *SizeImage;
  147.         ULONG         SizeWidth,
  148.                  SizeHeight,
  149.                  ArrowHeight;
  150.         UWORD         SizeType;
  151.  
  152.         if(Screen -> Flags & SCREENHIRES)
  153.         {
  154.             SizeWidth    = 18;
  155.             SizeHeight    = 10;
  156.  
  157.             SizeType    = SYSISIZE_MEDRES;
  158.         }
  159.         else
  160.         {
  161.             SizeWidth    = 13;
  162.             SizeHeight    = 11;
  163.  
  164.             SizeType    = SYSISIZE_LOWRES;
  165.         }
  166.  
  167.         if(SizeImage = (struct Image *)NewObject(NULL,"sysiclass",
  168.             SYSIA_Size,    SizeType,
  169.             SYSIA_Which,    SIZEIMAGE,
  170.             SYSIA_DrawInfo,    DrawInfo,
  171.         TAG_DONE))
  172.         {
  173.             GetAttr(IA_Width,    SizeImage,&SizeWidth);
  174.             GetAttr(IA_Height,    SizeImage,&SizeHeight);
  175.  
  176.             DisposeObject(SizeImage);
  177.  
  178.             RightBorderWidth = SizeWidth;
  179.  
  180.             if(UpImage = (struct Image *)NewObject(NULL,"sysiclass",
  181.                 SYSIA_Size,    SizeType,
  182.                 SYSIA_Which,    UPIMAGE,
  183.                 SYSIA_DrawInfo,    DrawInfo,
  184.             TAG_DONE))
  185.             {
  186.                 GetAttr(IA_Height,UpImage,&ArrowHeight);
  187.  
  188.                 if(DownImage = (struct Image *)NewObject(NULL,"sysiclass",
  189.                     SYSIA_Size,    SizeType,
  190.                     SYSIA_Which,    DOWNIMAGE,
  191.                     SYSIA_DrawInfo,    DrawInfo,
  192.                 TAG_DONE))
  193.                 {
  194.                     if(Scroller = NewObject(NULL,"propgclass",
  195.                         GA_ID,        GAD_SCROLLER,
  196.  
  197.                         GA_Top,        Screen -> WBorTop + Screen -> Font -> ta_YSize + 2,
  198.                         GA_RelHeight,    -(Screen -> WBorTop + Screen -> Font -> ta_YSize + 2 + SizeHeight + 1 + 2 * ArrowHeight),
  199.                         GA_Width,    SizeWidth - 8,
  200.                         GA_RelRight,    -(SizeWidth - 5),
  201.  
  202.                         GA_Immediate,    TRUE,
  203.                         GA_FollowMouse,    TRUE,
  204.                         GA_RelVerify,    TRUE,
  205.                         GA_RightBorder,    TRUE,
  206.  
  207.                         PGA_Freedom,    FREEVERT,
  208.                         PGA_NewLook,    TRUE,
  209.                         PGA_Borderless,    TRUE,
  210.  
  211.                         PGA_Visible,    1,
  212.                         PGA_Total,    1,
  213.                     TAG_DONE))
  214.                     {
  215.                         STATIC struct TagItem ArrowMappings[] = { GA_ID,GA_ID,TAG_END };
  216.  
  217.                         if(UpArrow = NewObject(NULL,"buttongclass",
  218.                             GA_ID,        GAD_UP,
  219.  
  220.                             GA_Image,    UpImage,
  221.                             GA_RelRight,    -(SizeWidth - 1),
  222.                             GA_RelBottom,    -(SizeHeight - 1 + 2 * ArrowHeight),
  223.                             GA_Height,    ArrowHeight,
  224.                             GA_Width,    SizeWidth,
  225.                             GA_Immediate,    TRUE,
  226.                             GA_RelVerify,    TRUE,
  227.                             GA_Previous,    Scroller,
  228.                             GA_RightBorder,    TRUE,
  229.  
  230.                             ICA_TARGET,    ICTARGET_IDCMP,
  231.                             ICA_MAP,    ArrowMappings,
  232.                         TAG_DONE))
  233.                         {
  234.                             if(DownArrow = NewObject(NULL,"buttongclass",
  235.                                 GA_ID,        GAD_DOWN,
  236.  
  237.                                 GA_Image,    DownImage,
  238.                                 GA_RelRight,    -(SizeWidth - 1),
  239.                                 GA_RelBottom,    -(SizeHeight - 1 + ArrowHeight),
  240.                                 GA_Height,    ArrowHeight,
  241.                                 GA_Width,    SizeWidth,
  242.                                 GA_Immediate,    TRUE,
  243.                                 GA_RelVerify,    TRUE,
  244.                                 GA_Previous,    UpArrow,
  245.                                 GA_RightBorder,    TRUE,
  246.  
  247.                                 ICA_TARGET,    ICTARGET_IDCMP,
  248.                                 ICA_MAP,    ArrowMappings,
  249.                             TAG_DONE))
  250.                                 Result = TRUE;
  251.                         }
  252.                     }
  253.                 }
  254.             }
  255.         }
  256.  
  257.         FreeScreenDrawInfo(Screen,DrawInfo);
  258.     }
  259.  
  260.     return(Result);
  261. }
  262.  
  263.     /* ReviewUpdatePot():
  264.      *
  265.      *    Update size and position of the scroller gadget.
  266.      */
  267.  
  268. STATIC VOID
  269. ReviewUpdatePot()
  270. {
  271.     if(ReviewGlobalLines)
  272.     {
  273.         SetGadgetAttrs(Scroller,ReviewWindow,NULL,
  274.             PGA_Top,    ReviewTop,
  275.             PGA_Visible,    ReviewLines,
  276.             PGA_Total,    ReviewGlobalLines,
  277.         TAG_DONE);
  278.     }
  279. }
  280.  
  281.     /* ReviewUp(LONG Count):
  282.      *
  283.      *    Move the contents of the review buffer up.
  284.      */
  285.  
  286. STATIC VOID __regargs
  287. ReviewUp(LONG Count)
  288. {
  289.     if(BufferLines)
  290.     {
  291.         if(Count == 1)
  292.         {
  293.             if(ReviewTop)
  294.             {
  295.                 WORD i;
  296.  
  297.                 for(i = ReviewMaxLines - 2 ; i >= 0 ; i--)
  298.                     ReviewLineWidths[i + 1] = ReviewLineWidths[i];
  299.  
  300.                 ReviewTop--;
  301.  
  302.                 ReviewWrites("\33[T");
  303.  
  304.                 ObtainSemaphore(BufferSemaphore);
  305.  
  306.                 PrintReviewLine(BufferLines[ReviewTop],1);
  307.  
  308.                 ReviewUpdatePot();
  309.  
  310.                 ReleaseSemaphore(BufferSemaphore);
  311.             }
  312.         }
  313.         else
  314.         {
  315.             LONG NewTop = ReviewTop;
  316.  
  317.             if(NewTop >= Count)
  318.                 NewTop -= Count;
  319.             else
  320.                 NewTop = 0;
  321.  
  322.             if(NewTop != ReviewTop)
  323.             {
  324.                 ScrollReview(NewTop);
  325.  
  326.                 ReviewUpdatePot();
  327.             }
  328.         }
  329.     }
  330. }
  331.  
  332.     /* ReviewDown(LONG Count):
  333.      *
  334.      *    Move the contents of the review buffer down.
  335.      */
  336.  
  337. STATIC VOID __regargs
  338. ReviewDown(LONG Count)
  339. {
  340.     if(BufferLines)
  341.     {
  342.         if(Count == 1)
  343.         {
  344.             if(ReviewTop + ReviewLines < Lines)
  345.             {
  346.                 LONG Last;
  347.                 WORD i;
  348.  
  349.                 for(i = 0 ; i < ReviewMaxLines - 1 ; i++)
  350.                     ReviewLineWidths[i] = ReviewLineWidths[i + 1];
  351.  
  352.                 ReviewTop++;
  353.  
  354.                 ReviewWrites("\33[S");
  355.  
  356.                 ObtainSemaphore(BufferSemaphore);
  357.  
  358.                 if((Last = ReviewTop + ReviewLines) < Lines)
  359.                     PrintReviewLine(BufferLines[Last],ReviewLines + 1);
  360.  
  361.                 ReviewUpdatePot();
  362.  
  363.                 ReleaseSemaphore(BufferSemaphore);
  364.             }
  365.         }
  366.         else
  367.         {
  368.             LONG NewTop = ReviewTop;
  369.  
  370.             if((NewTop + Count + ReviewLines) > Lines)
  371.             {
  372.                 if((NewTop = Lines - ReviewLines) < 0)
  373.                     NewTop = 0;
  374.             }
  375.             else
  376.                 NewTop += Count;
  377.  
  378.             if(NewTop != ReviewTop)
  379.             {
  380.                 ScrollReview(NewTop);
  381.  
  382.                 ReviewUpdatePot();
  383.             }
  384.         }
  385.     }
  386. }
  387.  
  388.     /* ReviewWrites(STRPTR String,...):
  389.      *
  390.      *    Write a string into the review buffer window.
  391.      */
  392.  
  393. STATIC VOID __stdargs
  394. ReviewWrites(STRPTR String,...)
  395. {
  396.     UBYTE    LocalBuffer[256];
  397.     va_list    VarArgs;
  398.  
  399.     va_start(VarArgs,String);
  400.     VSPrintf(LocalBuffer,String,VarArgs);
  401.     va_end(VarArgs);
  402.  
  403.     ReviewWriteRequest -> io_Command    = CMD_WRITE;
  404.     ReviewWriteRequest -> io_Data        = LocalBuffer;
  405.     ReviewWriteRequest -> io_Length        = strlen(LocalBuffer);
  406.  
  407.     DoIO(ReviewWriteRequest);
  408. }
  409.  
  410.     /* FilterReviewLine(register STRPTR Line,register LONG Length):
  411.      *
  412.      *    Replace non-printable characters in the text line
  413.      *    to be printed.
  414.      */
  415.  
  416.  
  417. STATIC STRPTR __regargs
  418. FilterReviewLine(register STRPTR Line,register LONG Length)
  419. {
  420.     STATIC UBYTE __far ISO[256] =
  421.     {
  422.          46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
  423.          46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
  424.          32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
  425.          48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
  426.          64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
  427.          80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
  428.          96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
  429.         112,113,114,115,116,117,118,119,120,121,122,123,124,125,126, 46,
  430.          46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
  431.          46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
  432.         160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
  433.         176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
  434.         192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
  435.         208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
  436.         224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
  437.         240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
  438.     };
  439.  
  440.     STATIC UBYTE __far TempBuffer[256];
  441.  
  442.     register STRPTR Destination = TempBuffer;
  443.  
  444.     while(Length--)
  445.         *Destination++ = ISO[*Line++];
  446.  
  447.     return(TempBuffer);
  448. }
  449.  
  450.     /* PrintReviewLine(STRPTR Buffer,LONG Line):
  451.      *
  452.      *    Write the contents of a buffer line into the review buffer window.
  453.      */
  454.  
  455. STATIC VOID __regargs
  456. PrintReviewLine(STRPTR Buffer,LONG Line)
  457. {
  458.     WORD Length = Buffer[-1];
  459.  
  460.     if(Length > ReviewColumns)
  461.         Length = ReviewColumns;
  462.  
  463.     ReviewWrites("\33[%ldH",Line);
  464.  
  465.     ReviewWriteRequest -> io_Command    = CMD_WRITE;
  466.     ReviewWriteRequest -> io_Data        = FilterReviewLine(Buffer,Length);
  467.     ReviewWriteRequest -> io_Length        = Length;
  468.  
  469.     DoIO(ReviewWriteRequest);
  470.  
  471.     if(Length < ReviewLineWidths[Line - 1])
  472.         ReviewWrites("\33[0K");
  473.  
  474.     ReviewLineWidths[Line - 1] = Length;
  475. }
  476.  
  477.     /* RefreshReview(LONG Top):
  478.      *
  479.      *    Refresh the contents of the review buffer window.
  480.      */
  481.  
  482. STATIC VOID __regargs
  483. RefreshReview(LONG Top)
  484. {
  485.     LONG i,Last,Line = 0;
  486.  
  487.     ObtainSemaphore(BufferSemaphore);
  488.  
  489.     ReviewGlobalLines = Lines;
  490.  
  491.     if((Last = Top + ReviewLines + 1) >= Lines)
  492.     {
  493.         Last = Lines;
  494.  
  495.         if((Top = Last - ReviewLines) < 0)
  496.             Top = 0;
  497.  
  498.         ReviewTop = Top;
  499.     }
  500.  
  501.     if(BufferLines)
  502.     {
  503.         for(i = Top ; i < Last ; i++)
  504.             PrintReviewLine(BufferLines[i],++Line);
  505.     }
  506.  
  507.     if(Line <= ReviewLines)
  508.     {
  509.         if(Line)
  510.         {
  511.             for(i = Line - 1 ; i < ReviewLines ; i++)
  512.                 ReviewLineWidths[i] = 0;
  513.         }
  514.  
  515.         if(Screen)
  516.             ReviewWrites("\33[0J\33[3%ldm",ReviewPen);
  517.         else
  518.             ReviewWrites("\33[0J");
  519.     }
  520.  
  521.     ReleaseSemaphore(BufferSemaphore);
  522. }
  523.  
  524.     /* MoveUp(VOID):
  525.      *
  526.      *    Move the review buffer contents up a line.
  527.      */
  528.  
  529. STATIC VOID
  530. MoveUp(VOID)
  531. {
  532.     LONG i;
  533.  
  534.     for(i = 0 ; i < ReviewMaxLines - 1 ; i++)
  535.         ReviewLineWidths[i] = ReviewLineWidths[i + 1];
  536.  
  537.     ReviewWrites("\33[S");
  538.  
  539.     ObtainSemaphore(BufferSemaphore);
  540.     PrintReviewLine(BufferLines[ReviewTop + ReviewLines],ReviewLines + 1);
  541.     ReleaseSemaphore(BufferSemaphore);
  542. }
  543.  
  544.     /* ScrollReview(LONG Top):
  545.      *
  546.      *    Refresh the contents of the review buffer window, reprint
  547.      *    as few lines as possible.
  548.      */
  549.  
  550. STATIC VOID __regargs
  551. ScrollReview(LONG Top)
  552. {
  553.     LONG i,Last,Line = 0,Delta,Total;
  554.  
  555.     ObtainSemaphore(BufferSemaphore);
  556.  
  557.     ReviewGlobalLines = Lines;
  558.  
  559.     Delta = Top - ReviewTop;
  560.  
  561.     ReviewTop = Top;
  562.  
  563.     if((Last = Top + ReviewLines + 1) >= Lines)
  564.         Last = Lines;
  565.  
  566.     Total = Last - Top;
  567.  
  568.     if(ABS(Delta) < ReviewLines)
  569.     {
  570.         if(!Delta)
  571.         {
  572.             ReleaseSemaphore(BufferSemaphore);
  573.  
  574.             return;
  575.         }
  576.         else
  577.         {
  578.             if(Delta < 0)
  579.             {
  580.                 Last = Top - Delta;
  581.  
  582.                 for(i = ReviewMaxLines - 1 ; i > -Delta ; i--)
  583.                     ReviewLineWidths[i] = ReviewLineWidths[i + Delta];
  584.  
  585.                 ReviewWrites("\33[%ldT",-Delta);
  586.             }
  587.             else
  588.             {
  589.                 for(i = Delta ; i < ReviewMaxLines ; i++)
  590.                     ReviewLineWidths[i - Delta] = ReviewLineWidths[i];
  591.  
  592.                 Top += ReviewLines - Delta;
  593.                 Line = ReviewLines - Delta;
  594.  
  595.                 ReviewWrites("\33[%ldS",Delta);
  596.             }
  597.         }
  598.     }
  599.  
  600.     if(BufferLines)
  601.     {
  602.         for(i = Top ; i < Last ; i++)
  603.             PrintReviewLine(BufferLines[i],++Line);
  604.     }
  605.  
  606.     if(Total <= ReviewLines)
  607.         ReviewWrites("\33[0J");
  608.  
  609.     ReleaseSemaphore(BufferSemaphore);
  610. }
  611.  
  612.     /* ReviewQuery():
  613.      *
  614.      *    Update the current review buffer window dimensions.
  615.      */
  616.  
  617. STATIC BYTE
  618. ReviewQuery()
  619. {
  620.     struct ConUnit    *Unit = (struct ConUnit *)ReviewWriteRequest -> io_Unit;
  621.     BYTE         Refresh = FALSE;
  622.  
  623.     memset(ReviewLineWidths,0,ReviewMaxLines);
  624.  
  625.     if(ReviewColumns != Unit -> cu_XMax)
  626.     {
  627.         Refresh = TRUE;
  628.  
  629.         ReviewColumns = Unit -> cu_XMax;
  630.     }
  631.  
  632.     if(ReviewLines != Unit -> cu_YMax)
  633.     {
  634.         Refresh = TRUE;
  635.  
  636.         if(Unit -> cu_YMax < ReviewGlobalLines)
  637.         {
  638.             LONG Delta = Unit -> cu_YMax - ReviewLines;
  639.  
  640.             ReviewLines = Unit -> cu_YMax;
  641.  
  642.             if(Delta > 0)
  643.             {
  644.                 if((ReviewTop = ReviewTop - Delta) < 0)
  645.                     ReviewTop = 0;
  646.             }
  647.             else
  648.             {
  649.                 ReviewTop -= Delta;
  650.  
  651.                 if(ReviewTop + ReviewLines > ReviewGlobalLines)
  652.                     ReviewTop = ReviewGlobalLines - ReviewLines;
  653.             }
  654.         }
  655.         else
  656.         {
  657.             ReviewTop    = 0;
  658.             ReviewLines    = ReviewGlobalLines;
  659.         }
  660.     }
  661.  
  662.     if(Refresh)
  663.         ReviewUpdatePot();
  664.  
  665.     return(Refresh);
  666. }
  667.  
  668.     /* GetReviewChar(BYTE WaitForIt):
  669.      *
  670.      *    Get the next character present at the console read port.
  671.      */
  672.  
  673. STATIC UBYTE __regargs
  674. GetReviewChar(BYTE WaitForIt)
  675. {
  676.     UBYTE Char;
  677.  
  678.     if(!WaitForIt)
  679.     {
  680.         if(!CheckIO(ReviewReadRequest))
  681.             return(0);
  682.     }
  683.  
  684.     WaitIO(ReviewReadRequest);
  685.  
  686.     Char = ReviewChar;
  687.  
  688.     ReviewReadRequest -> io_Command    = CMD_READ;
  689.     ReviewReadRequest -> io_Data    = &ReviewChar;
  690.     ReviewReadRequest -> io_Length    = 1;
  691.  
  692.     SetSignal(0,SIG_REVIEWPORT);
  693.  
  694.     SendIO(ReviewReadRequest);
  695.  
  696.     return(Char);
  697. }
  698.  
  699.     /* MarkReviewLine(STRPTR Buffer,LONG Line,LONG Column,LONG Len):
  700.      *
  701.      *    Similar to PrintReviewLine(), but also allows to mark a
  702.      *    certain word on the line.
  703.      */
  704.  
  705. STATIC VOID __regargs
  706. MarkReviewLine(STRPTR Buffer,LONG Line,LONG Column,LONG Len)
  707. {
  708.     WORD Length = Buffer[-1];
  709.  
  710.     if(Length > ReviewColumns)
  711.         Length = ReviewColumns;
  712.  
  713.     ReviewWrites("\33[%ldH",Line);
  714.  
  715.     if(Length <= Column)
  716.     {
  717.         ReviewWriteRequest -> io_Command    = CMD_WRITE;
  718.         ReviewWriteRequest -> io_Data        = Buffer;
  719.         ReviewWriteRequest -> io_Length        = Length;
  720.  
  721.         DoIO(ReviewWriteRequest);
  722.  
  723.         ReviewWrites("\33[0K");
  724.     }
  725.     else
  726.     {
  727.         ReviewWriteRequest -> io_Command    = CMD_WRITE;
  728.         ReviewWriteRequest -> io_Data        = Buffer;
  729.         ReviewWriteRequest -> io_Length        = Column;
  730.  
  731.         DoIO(ReviewWriteRequest);
  732.  
  733.         ReviewWrites("\33[7;3%ldm",ReviewPen);
  734.  
  735.         ReviewWriteRequest -> io_Command    = CMD_WRITE;
  736.         ReviewWriteRequest -> io_Data        = &Buffer[Column];
  737.         ReviewWriteRequest -> io_Length        = Len;
  738.  
  739.         DoIO(ReviewWriteRequest);
  740.  
  741.         ReviewWrites("\33[0;3%ldm",ReviewPen);
  742.  
  743.         if(Column + Len < Length)
  744.         {
  745.             ReviewWriteRequest -> io_Command    = CMD_WRITE;
  746.             ReviewWriteRequest -> io_Data        = &Buffer[Column + Len];
  747.             ReviewWriteRequest -> io_Length        = Length - (Column + Len);
  748.  
  749.             DoIO(ReviewWriteRequest);
  750.         }
  751.  
  752.         ReviewWrites("\33[0K");
  753.     }
  754. }
  755.  
  756.     /* ReviewMarkArea(LONG Top,LONG Column,LONG Line,LONG Len,BYTE FullRefresh):
  757.      *
  758.      *    Mark a word on the current display.
  759.      */
  760.  
  761. STATIC VOID __regargs
  762. ReviewMarkArea(LONG Top,LONG Column,LONG Line,LONG Len,BYTE FullRefresh)
  763. {
  764.     STATIC LONG LastMarked = -1;
  765.  
  766.     LONG i,Last,LineIndex = 0;
  767.  
  768.     ReviewGlobalLines = Lines;
  769.  
  770.     ObtainSemaphore(BufferSemaphore);
  771.  
  772.     if((Last = Top + ReviewLines + 1) >= Lines)
  773.         Last = Lines;
  774.  
  775.     if(FullRefresh)
  776.     {
  777.         if(BufferLines)
  778.         {
  779.             for(i = Top ; i < Last ; i++)
  780.             {
  781.                 if(i != Line)
  782.                     PrintReviewLine(BufferLines[i],++LineIndex);
  783.                 else
  784.                     MarkReviewLine(BufferLines[i],++LineIndex,Column,Len);
  785.             }
  786.         }
  787.  
  788.         if(LineIndex <= ReviewLines)
  789.             ReviewWrites("\33[0J");
  790.     }
  791.     else
  792.     {
  793.         if(BufferLines)
  794.         {
  795.             for(i = Top ; i < Last ; i++)
  796.             {
  797.                 LineIndex++;
  798.  
  799.                 if(i == LastMarked)
  800.                     PrintReviewLine(BufferLines[i],LineIndex);
  801.  
  802.                 if(i == Line)
  803.                     MarkReviewLine(BufferLines[i],LineIndex,Column,Len);
  804.             }
  805.         }
  806.     }
  807.  
  808.     LastMarked = Line;
  809.  
  810.     ReleaseSemaphore(BufferSemaphore);
  811. }
  812.  
  813.     /* ReviewSearch(struct SearchInfo *SearchInfo):
  814.      *
  815.      *    Search for a certain word in the text buffer.
  816.      */
  817.  
  818. STATIC VOID __regargs
  819. ReviewSearch(struct SearchInfo *SearchInfo,STRPTR SearchBuffer)
  820. {
  821.     LT_LockWindow(ReviewWindow);
  822.  
  823.     if(Lines)
  824.     {
  825.         LONG LineNumber;
  826.  
  827.         ObtainSemaphore(BufferSemaphore);
  828.  
  829.         LineNumber = SearchTextBuffer(SearchInfo);
  830.  
  831.         ReleaseSemaphore(BufferSemaphore);
  832.  
  833.         if(LineNumber == -1)
  834.         {
  835.             RefreshReview(ReviewTop);
  836.  
  837.             MyEasyRequest(ReviewWindow,LocaleString(MSG_TERMBUFFER_DID_NOT_FIND_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),SearchBuffer);
  838.  
  839.             SearchInfo -> FoundY = -1;
  840.         }
  841.         else
  842.         {
  843.             if(LineNumber < ReviewTop || LineNumber > ReviewTop + ReviewLines)
  844.             {
  845.                 if(LineNumber + ReviewLines > Lines)
  846.                 {
  847.                     ReviewTop = Lines - ReviewLines;
  848.  
  849.                     if(ReviewTop < 0)
  850.                         ReviewTop = 0;
  851.                 }
  852.                 else
  853.                     ReviewTop = LineNumber;
  854.  
  855.                 ReviewUpdatePot();
  856.  
  857.                 ReviewMarkArea(ReviewTop,SearchInfo -> FoundX,LineNumber,SearchInfo -> PatternWidth,TRUE);
  858.             }
  859.             else
  860.                 ReviewMarkArea(ReviewTop,SearchInfo -> FoundX,LineNumber,SearchInfo -> PatternWidth,FALSE);
  861.         }
  862.     }
  863.     else
  864.         MyEasyRequest(ReviewWindow,LocaleString(MSG_GLOBAL_NOTHING_IN_THE_BUFFER_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  865.  
  866.     LT_UnlockWindow(ReviewWindow);
  867. }
  868.  
  869. STATIC VOID
  870. LocalDeleteReview(VOID)
  871. {
  872.     if(ReviewReadRequest)
  873.     {
  874.         if(ReviewReadRequest -> io_Device)
  875.         {
  876.             if(!CheckIO(ReviewReadRequest))
  877.                 AbortIO(ReviewReadRequest);
  878.  
  879.             WaitIO(ReviewReadRequest);
  880.         }
  881.  
  882.         FreeVecPooled(ReviewReadRequest);
  883.  
  884.         ReviewReadRequest = NULL;
  885.     }
  886.  
  887.     if(ReviewWriteRequest)
  888.     {
  889.         if(ReviewWriteRequest -> io_Device)
  890.             CloseDevice(ReviewWriteRequest);
  891.  
  892.         DeleteIORequest(ReviewWriteRequest);
  893.  
  894.         ReviewWriteRequest = NULL;
  895.     }
  896.  
  897.     if(ReviewWindow)
  898.     {
  899.         PutWindowInfo(WINDOW_REVIEW,ReviewWindow -> LeftEdge,ReviewWindow -> TopEdge,ReviewWindow -> Width,ReviewWindow -> Height);
  900.  
  901.         LT_DeleteWindowLock(ReviewWindow);
  902.  
  903.         ClearMenuStrip(ReviewWindow);
  904.  
  905.         CloseWindow(ReviewWindow);
  906.  
  907.         ReviewWindow = NULL;
  908.     }
  909.  
  910.     if(LocalFont)
  911.     {
  912.         CloseFont(LocalFont);
  913.  
  914.         LocalFont = NULL;
  915.     }
  916.  
  917.     if(ReviewMenuStrip)
  918.     {
  919.         FreeMenus(ReviewMenuStrip);
  920.  
  921.         ReviewMenuStrip = NULL;
  922.     }
  923.  
  924.     ReviewDeleteScroller();
  925.  
  926.     if(ReviewWritePort)
  927.     {
  928.         DeleteMsgPort(ReviewWritePort);
  929.  
  930.         ReviewWritePort = NULL;
  931.     }
  932.  
  933.     if(ReviewPort)
  934.     {
  935.         DeleteMsgPort(ReviewPort);
  936.  
  937.         ReviewPort = NULL;
  938.     }
  939.  
  940.     if(ReviewSignal != -1)
  941.     {
  942.         FreeSignal(ReviewSignal);
  943.  
  944.         ReviewSignal = -1;
  945.     }
  946.  
  947.     if(ReviewLineWidths)
  948.     {
  949.         FreeVecPooled(ReviewLineWidths);
  950.  
  951.         ReviewLineWidths = NULL;
  952.     }
  953.  
  954.     if(ReviewQueue)
  955.     {
  956.         DeleteMsgQueue(ReviewQueue);
  957.  
  958.         ReviewQueue = NULL;
  959.     }
  960. }
  961.  
  962. STATIC BOOLEAN
  963. LocalCreateReview(VOID)
  964. {
  965.     if(ReviewBox . Left == -1)
  966.     {
  967.         ReviewBox . Left    = 0;
  968.         ReviewBox . Top        = Window -> WScreen -> BarHeight + 1;
  969.         ReviewBox . Width    = Window -> WScreen -> Width;
  970.         ReviewBox . Height    = Window -> WScreen -> Height - (Window -> WScreen -> BarHeight + 1);
  971.     }
  972.  
  973.     if((ReviewSignal = AllocSignal(-1)) != -1)
  974.     {
  975.         if(ReviewQueue = CreateMsgQueue(NULL,0))
  976.         {
  977.             if(ReviewCreateScroller(Window -> WScreen))
  978.             {
  979.                 LocalizeMenu(ReviewMenu,MSG_TERMREVIEW_PROJECT_MEN);
  980.  
  981.                 if(ReviewMenuStrip = CreateMenus(ReviewMenu,TAG_DONE))
  982.                 {
  983.                     if(LayoutMenus(ReviewMenuStrip,VisualInfo,
  984.                         AmigaGlyph ? GTMN_AmigaKey :  TAG_IGNORE, AmigaGlyph,
  985.                         CheckGlyph ? GTMN_Checkmark : TAG_IGNORE, CheckGlyph,
  986.  
  987.                         GTMN_TextAttr,        &UserFont,
  988.                         GTMN_NewLookMenus,    TRUE,
  989.                     TAG_DONE))
  990.                     {
  991.                         LONG    Left    = 0,
  992.                             Top    = 0,
  993.                             Width    = 0,
  994.                             Height    = 0;
  995.  
  996.                         GetWindowInfo(WINDOW_REVIEW,&Left,&Top,&Width,&Height,NULL,Window -> WScreen -> WBorTop + Window -> WScreen -> WBorBottom + 1 + Window -> WScreen -> Font -> ta_YSize + 10 * CurrentFont -> tf_YSize);
  997.  
  998.                         if(ReviewWindow = OpenWindowTags(NULL,
  999.                             WA_Left,        Left,
  1000.                             WA_Top,            Top,
  1001.                             WA_Width,        Width,
  1002.                             WA_Height,        Height,
  1003.                             WA_MinWidth,        Window -> WScreen -> WBorLeft + RightBorderWidth + 15 * CurrentFont -> tf_XSize,
  1004.                             WA_MinHeight,        Window -> WScreen -> WBorTop + Window -> WScreen -> WBorBottom + 1 + Window -> WScreen -> Font -> ta_YSize + 2 * CurrentFont -> tf_YSize,
  1005.                             WA_MaxWidth,        Window -> WScreen -> Width,
  1006.                             WA_MaxHeight,        Window -> WScreen -> Height,
  1007.                             WA_DragBar,        TRUE,
  1008.                             WA_CloseGadget,        TRUE,
  1009.                             WA_DepthGadget,        TRUE,
  1010.                             WA_SizeGadget,        TRUE,
  1011.                             WA_SizeBRight,        TRUE,
  1012.                             WA_MenuHelp,        TRUE,
  1013.                             WA_IDCMP,        IDCMP_IDCMPUPDATE | IDCMP_GADGETDOWN | IDCMP_SIZEVERIFY | IDCMP_MOUSEMOVE | IDCMP_MENUPICK | IDCMP_MENUHELP,
  1014.                             WA_Title,        LocaleString(MSG_TERMREVIEW_REVIEWBUFFER_TXT),
  1015.                             WA_CustomScreen,    Window -> WScreen,
  1016.                             WA_SimpleRefresh,    TRUE,
  1017.                             WA_RMBTrap,        TRUE,
  1018.                             WA_Activate,        TRUE,
  1019.                             WA_NewLookMenus,    TRUE,
  1020.                             WA_Zoom,        &ReviewBox,
  1021.                             WA_Gadgets,        Scroller,
  1022.  
  1023.                             AmigaGlyph ? WA_AmigaKey  : TAG_IGNORE, AmigaGlyph,
  1024.                             CheckGlyph ? WA_Checkmark : TAG_IGNORE, CheckGlyph,
  1025.                         TAG_DONE))
  1026.                         {
  1027.                             ReviewMaxLines = (ReviewWindow -> WScreen -> Height - (ReviewWindow -> BorderTop + ReviewWindow -> BorderBottom)) / CurrentFont -> tf_YSize;
  1028.  
  1029.                             if(ReviewLineWidths = (UBYTE *)AllocVecPooled(ReviewMaxLines,MEMF_ANY | MEMF_CLEAR))
  1030.                             {
  1031.                                 SetMenuStrip(ReviewWindow,ReviewMenuStrip);
  1032.  
  1033.                                 memcpy(&LocalTextFont,&TextAttr,sizeof(struct TTextAttr));
  1034.  
  1035.                                 LocalTextFont . tta_Name    = LocalTextFontName;
  1036.                                 LocalTextFont . tta_YSize    = Config -> TerminalConfig -> TextFontHeight;
  1037.  
  1038.                                 strcpy(LocalTextFontName,Config -> TerminalConfig -> TextFontName);
  1039.  
  1040.                                 if(!Config -> CaptureConfig -> ConvertChars && Config -> TerminalConfig -> FontMode != FONT_STANDARD)
  1041.                                 {
  1042.                                     strcpy(LocalTextFontName,Config -> TerminalConfig -> IBMFontName);
  1043.  
  1044.                                     LocalTextFont . tta_YSize = Config -> TerminalConfig -> IBMFontHeight;
  1045.                                 }
  1046.  
  1047.                                 if(LocalFont = OpenDiskFont(&LocalTextFont))
  1048.                                     SetFont(ReviewWindow -> RPort,LocalFont);
  1049.  
  1050.                                 if(ReviewWritePort = CreateMsgPort())
  1051.                                 {
  1052.                                     if(ReviewPort = CreateMsgPort())
  1053.                                     {
  1054.                                         if(ReviewWriteRequest = CreateIORequest(ReviewPort,sizeof(struct IOStdReq)))
  1055.                                         {
  1056.                                             if(ReviewReadRequest = (struct IOStdReq *)AllocVecPooled(sizeof(struct IOStdReq),MEMF_ANY | MEMF_CLEAR))
  1057.                                             {
  1058.                                                 ReviewWriteRequest -> io_Data = ReviewWindow;
  1059.  
  1060.                                                 if(!OpenDevice("console.device",CONU_SNIPMAP,ReviewWriteRequest,CONFLAG_NODRAW_ON_NEWSIZE))
  1061.                                                 {
  1062.                                                     CopyMem(ReviewWriteRequest,ReviewReadRequest,sizeof(struct IOStdReq));
  1063.  
  1064.                                                     ReviewReadRequest -> io_Message . mn_ReplyPort = ReviewPort;
  1065.  
  1066.                                                     ReviewReadRequest -> io_Command    = CMD_READ;
  1067.                                                     ReviewReadRequest -> io_Data    = &ReviewChar;
  1068.                                                     ReviewReadRequest -> io_Length    = 1;
  1069.  
  1070.                                                     SendIO(ReviewReadRequest);
  1071.  
  1072.                                                     switch(Config -> ScreenConfig -> ColourMode)
  1073.                                                     {
  1074.                                                         case COLOUR_AMIGA:
  1075.                                                         case COLOUR_MONO:
  1076.  
  1077.                                                             ReviewPen = 1;
  1078.                                                             break;
  1079.  
  1080.                                                         case COLOUR_EIGHT:
  1081.                                                         case COLOUR_SIXTEEN:
  1082.  
  1083.                                                             ReviewPen = 7;
  1084.                                                             break;
  1085.                                                     }
  1086.  
  1087.                                                     ReviewPen = GetPenIndex(ReviewPen) & 7;
  1088.  
  1089.                                                     if(Screen)
  1090.                                                         ReviewWrites("\33[0 p\33[11;12\173\33[3%ldm",ReviewPen);
  1091.                                                     else
  1092.                                                         ReviewWrites("\33[0 p\33[11;12\173");
  1093.  
  1094.                                                     ObtainSemaphore(BufferSemaphore);
  1095.  
  1096.                                                     if(ReviewTop == -1 || !Config -> CaptureConfig -> RememberBufferWindow)
  1097.                                                     {
  1098.                                                         switch(Config -> CaptureConfig -> OpenBufferWindow)
  1099.                                                         {
  1100.                                                             case BUFFER_TOP:
  1101.  
  1102.                                                                 ReviewTop = 0;
  1103.                                                                 break;
  1104.  
  1105.                                                             case BUFFER_END:
  1106.  
  1107.                                                                 if((ReviewTop = Lines - ReviewLines) < 0)
  1108.                                                                     ReviewTop = 0;
  1109.  
  1110.                                                                 break;
  1111.  
  1112.                                                             default:
  1113.  
  1114.                                                                 ReviewTop = 0;
  1115.                                                                 break;
  1116.                                                         }
  1117.                                                     }
  1118.  
  1119.                                                     if(ReviewTop > Lines - ReviewLines)
  1120.                                                     {
  1121.                                                         if((ReviewTop = Lines - ReviewLines) < 0)
  1122.                                                             ReviewTop = 0;
  1123.                                                     }
  1124.  
  1125.                                                     ReviewGlobalLines = Lines;
  1126.  
  1127.                                                     ReleaseSemaphore(BufferSemaphore);
  1128.  
  1129.                                                     ReviewQuery();
  1130.  
  1131.                                                     RefreshReview(ReviewTop);
  1132.  
  1133.                                                     ReviewUpdatePot();
  1134.  
  1135.                                                     ReviewWindow -> Flags &= ~WFLG_RMBTRAP;
  1136.  
  1137.                                                     return(TRUE);
  1138.                                                 }
  1139.                                             }
  1140.                                         }
  1141.                                     }
  1142.                                 }
  1143.                             }
  1144.                         }
  1145.                     }
  1146.                 }
  1147.             }
  1148.         }
  1149.     }
  1150.  
  1151.     LocalDeleteReview();
  1152.  
  1153.     return(FALSE);
  1154. }
  1155.  
  1156.     /* LocalUpdateReview():
  1157.      *
  1158.      *    Update the contents of the review buffer window.
  1159.      */
  1160.  
  1161. STATIC VOID __regargs
  1162. LocalUpdateReview(BYTE Force)
  1163. {
  1164.     if(Force)
  1165.     {
  1166.         if(Lines)
  1167.         {
  1168.             if(ReviewTop > 0)
  1169.             {
  1170.                 SetGadgetAttrs(Scroller,ReviewWindow,NULL,
  1171.                     PGA_Top,--ReviewTop,
  1172.                 TAG_DONE);
  1173.             }
  1174.             else
  1175.                 MoveUp();
  1176.         }
  1177.     }
  1178.     else
  1179.     {
  1180.         if(Lines >= ReviewGlobalLines && ReviewGlobalLines <= ReviewLines)
  1181.         {
  1182.             if(ReviewLines < ((struct ConUnit *)ReviewWriteRequest -> io_Unit) -> cu_YMax)
  1183.             {
  1184.                 if(((struct ConUnit *)ReviewWriteRequest -> io_Unit) -> cu_YMax < Lines)
  1185.                     ReviewLines = ((struct ConUnit *)ReviewWriteRequest -> io_Unit) -> cu_YMax;
  1186.                 else
  1187.                     ReviewLines = Lines;
  1188.             }
  1189.  
  1190.             RefreshReview(ReviewTop);
  1191.         }
  1192.     }
  1193.  
  1194.     ReviewGlobalLines = Lines;
  1195.  
  1196.     if(!Lines)
  1197.     {
  1198.         SetGadgetAttrs(Scroller,ReviewWindow,NULL,
  1199.             PGA_Top,    ReviewTop = 0,
  1200.             PGA_Visible,    1,
  1201.             PGA_Total,    1,
  1202.         TAG_DONE);
  1203.  
  1204.         ReviewWrites("\f\33[3%ldm",ReviewPen);
  1205.     }
  1206.     else
  1207.         ReviewUpdatePot();
  1208. }
  1209.  
  1210.     /* LocalMoveReview(BYTE Mode):
  1211.      *
  1212.      *    Move the currently visible review area.
  1213.      */
  1214.  
  1215. STATIC VOID __regargs
  1216. LocalMoveReview(BYTE Mode)
  1217. {
  1218.     LONG NewTop;
  1219.  
  1220.     switch(Mode)
  1221.     {
  1222.         case REVIEW_MOVE_TOP:
  1223.  
  1224.             if(ReviewTop)
  1225.             {
  1226.                 ScrollReview(0);
  1227.  
  1228.                 ReviewUpdatePot();
  1229.             }
  1230.  
  1231.             break;
  1232.  
  1233.         case REVIEW_MOVE_BOTTOM:
  1234.  
  1235.             NewTop = Lines - ReviewLines;
  1236.  
  1237.             if(NewTop < 0)
  1238.                 NewTop = 0;
  1239.  
  1240.             if(ReviewTop != NewTop)
  1241.             {
  1242.                 ScrollReview(NewTop);
  1243.  
  1244.                 ReviewUpdatePot();
  1245.             }
  1246.  
  1247.             break;
  1248.  
  1249.         case REVIEW_MOVE_UP:
  1250.  
  1251.             ReviewUp(ReviewLines);
  1252.             break;
  1253.  
  1254.         case REVIEW_MOVE_DOWN:
  1255.  
  1256.             ReviewDown(ReviewLines);
  1257.             break;
  1258.     }
  1259. }
  1260.  
  1261. STATIC VOID __stdargs
  1262. ReviewClientDestructor(struct DataMsg *Item)
  1263. {
  1264.     Signal((struct Task *)Item -> Client,Item -> Mask);
  1265. }
  1266.  
  1267. STATIC VOID __regargs
  1268. ReviewSerWrite(APTR Data,LONG Size)
  1269. {
  1270.     struct DataMsg Msg;
  1271.  
  1272.     InitMsgItem(&Msg,ReviewClientDestructor);
  1273.  
  1274.     Msg . Type    = DATAMSGTYPE_WRITE;
  1275.     Msg . Data    = Data;
  1276.     Msg . Size    = Size;
  1277.     Msg . Client    = ReviewProcess;
  1278.     Msg . Mask    = ReviewSignal;
  1279.  
  1280.     Forbid();
  1281.  
  1282.     ClrSignal(Msg . Mask);
  1283.  
  1284.     PutMsgItem(SpecialQueue,(struct MsgItem *)&Msg);
  1285.  
  1286.     Wait(Msg . Mask);
  1287.  
  1288.     Permit();
  1289. }
  1290.  
  1291. STATIC VOID __saveds
  1292. ReviewProcessEntry(VOID)
  1293. {
  1294.     struct Process *Father = ThisProcess;
  1295.  
  1296.     if(LocalCreateReview())
  1297.     {
  1298.         UBYTE             SearchBuffer[256];
  1299.         struct Hook         HistoryHook;
  1300.         ULONG             Signals;
  1301.         BOOLEAN             Done        = FALSE;
  1302.         struct SearchInfo    *SearchInfo    = NULL;
  1303.         struct SearchContext    *Context    = NULL;
  1304.  
  1305.         HistoryHook . h_Data = &ReviewBufferHistory;
  1306.  
  1307.         Forbid();
  1308.  
  1309.         ReviewProcess = (struct Process *)SysBase -> ThisTask;
  1310.  
  1311.         Signal(ThisProcess,SIG_HANDSHAKE);
  1312.  
  1313.         Permit();
  1314.  
  1315.         do
  1316.         {
  1317.             Signals = Wait(SIG_KILL | SIG_REVIEWPORT | SIG_REVIEWWINDOW | ReviewQueue -> SigMask);
  1318.  
  1319.             if(Signals & SIG_KILL)
  1320.                 break;
  1321.  
  1322.             if(Signals & SIG_REVIEWPORT)
  1323.             {
  1324.                 UBYTE Char;
  1325.  
  1326.                     /* Control sequence available? */
  1327.  
  1328.                 if((Char = GetReviewChar(FALSE)) == CSI)
  1329.                 {
  1330.                     UBYTE    InputBuffer[257];
  1331.                     WORD    Count = 0;
  1332.  
  1333.                         /* Try to read the entire sequence. */
  1334.  
  1335.                     while(Char = GetReviewChar(FALSE))
  1336.                     {
  1337.                         InputBuffer[Count++] = Char;
  1338.  
  1339.                         if(Char != ' ' && Char != ';' && (Char < '0' || Char > '9'))
  1340.                             break;
  1341.                     }
  1342.  
  1343.                         /* Provide termination. */
  1344.  
  1345.                     InputBuffer[Count] = 0;
  1346.  
  1347.                         /* Raw event? */
  1348.  
  1349.                     if(!strcmp(InputBuffer,"?~"))
  1350.                         GuideDisplay(CONTEXT_TEXTBUFFER);
  1351.  
  1352.                     if(!strcmp(InputBuffer,"A"))
  1353.                         ReviewUp(1);
  1354.  
  1355.                     if(!strcmp(InputBuffer,"B"))
  1356.                         ReviewDown(1);
  1357.  
  1358.                     if(!strcmp(InputBuffer,"T"))
  1359.                         ReviewUp(ReviewLines);
  1360.  
  1361.                     if(!strcmp(InputBuffer,"S"))
  1362.                         ReviewDown(ReviewLines);
  1363.  
  1364.                     if(!memcmp(InputBuffer,"11;",3))
  1365.                     {
  1366.                         Done = TRUE;
  1367.  
  1368.                         if(!(SetSignal(0,SIG_KILL) & SIG_KILL))
  1369.                             Father = NULL;
  1370.                     }
  1371.  
  1372.                     if(!memcmp(InputBuffer,"12;",3))
  1373.                     {
  1374.                         if(ReviewQuery())
  1375.                             RefreshReview(ReviewTop);
  1376.                     }
  1377.  
  1378.                     if(!strcmp(InputBuffer,"0 v"))
  1379.                     {
  1380.                         struct DataMsg Msg;
  1381.  
  1382.                         InitMsgItem(&Msg,ReviewClientDestructor);
  1383.  
  1384.                         Msg . Type    = DATAMSGTYPE_WRITECLIP;
  1385.                         Msg . Size    = Config -> ClipConfig -> ClipboardUnit;
  1386.                         Msg . Client    = ReviewProcess;
  1387.                         Msg . Mask    = ReviewSignal;
  1388.  
  1389.                         Forbid();
  1390.  
  1391.                         ClrSignal(Msg . Mask);
  1392.  
  1393.                         PutMsgItem(SpecialQueue,(struct MsgItem *)&Msg);
  1394.  
  1395.                         Wait(Msg . Mask);
  1396.  
  1397.                         Permit();
  1398.                     }
  1399.                 }
  1400.                 else
  1401.                 {
  1402.                     if(Char)
  1403.                     {
  1404.                         if(Config -> SerialConfig -> StripBit8)
  1405.                             Char &= 0x7F;
  1406.  
  1407.                         if(Status == STATUS_HOLDING)
  1408.                         {
  1409.                             if(Char == XOF)
  1410.                             {
  1411.                                 ReviewSerWrite(&Char,1);
  1412.  
  1413.                                 Status = STATUS_READY;
  1414.                             }
  1415.                         }
  1416.                         else
  1417.                         {
  1418.                                 /* Convert chars
  1419.                                  * as approriate.
  1420.                                  */
  1421.  
  1422.                             if(Char == '\n')
  1423.                             {
  1424.                                 switch(Config -> TerminalConfig -> SendLF)
  1425.                                 {
  1426.                                     case EOL_LF:
  1427.  
  1428.                                         goto SendIt;
  1429.  
  1430.                                     case EOL_LFCR:
  1431.  
  1432.                                         ReviewSerWrite("\n\r",2);
  1433.                                         break;
  1434.  
  1435.                                     case EOL_CRLF:
  1436.  
  1437.                                         ReviewSerWrite("\r\n",2);
  1438.                                         break;
  1439.  
  1440.                                     case EOL_CR:
  1441.  
  1442.                                         ReviewSerWrite("\r",1);
  1443.                                         break;
  1444.                                 }
  1445.                             }
  1446.  
  1447.                             if(Char == '\r')
  1448.                             {
  1449.                                 switch(Config -> TerminalConfig -> SendCR)
  1450.                                 {
  1451.                                     case EOL_CR:
  1452.  
  1453.                                         goto SendIt;
  1454.  
  1455.                                     case EOL_LFCR:
  1456.  
  1457.                                         ReviewSerWrite("\n\r",2);
  1458.                                         break;
  1459.  
  1460.                                     case EOL_CRLF:
  1461.  
  1462.                                         ReviewSerWrite("\r\n",2);
  1463.                                         break;
  1464.  
  1465.                                     case EOL_LF:
  1466.  
  1467.                                         ReviewSerWrite("\n",1);
  1468.                                         break;
  1469.                                 }
  1470.                             }
  1471.  
  1472.                                 /* Stop in/output. */
  1473.  
  1474.                             if(Char == XON)
  1475.                             {
  1476.                                 if(Config -> SerialConfig -> PassThrough)
  1477.                                     ReviewSerWrite(&Char,1);
  1478.  
  1479.                                 if(Config -> SerialConfig -> xONxOFF)
  1480.                                     Status = STATUS_HOLDING;
  1481.                             }
  1482.  
  1483.                                 /* Restart in/output. */
  1484.  
  1485.                             if(Char == XOF)
  1486.                             {
  1487.                                 if(Config -> SerialConfig -> PassThrough)
  1488.                                     ReviewSerWrite(&Char,1);
  1489.  
  1490.                                 if(Status == STATUS_HOLDING)
  1491.                                     Status = STATUS_READY;
  1492.                             }
  1493.  
  1494.                                 /* Convert special
  1495.                                  * Amiga characters into
  1496.                                  * alien IBM dialect.
  1497.                                  */
  1498.  
  1499. SendIt:                            if(Config -> TerminalConfig -> FontMode == FONT_IBM)
  1500.                             {
  1501.                                 if(IBMConversion[Char])
  1502.                                     ReviewSerWrite(&IBMConversion[Char],1);
  1503.                                 else
  1504.                                     ReviewSerWrite(&Char,1);
  1505.                             }
  1506.                             else
  1507.                                 ReviewSerWrite(&Char,1);
  1508.                         }
  1509.                     }
  1510.                 }
  1511.             }
  1512.  
  1513.             if(Signals & SIG_REVIEWWINDOW)
  1514.             {
  1515.                 struct IntuiMessage    *Message;
  1516.                 struct MenuItem        *MenuItem;
  1517.                 struct TagItem        *TagList;
  1518.                 ULONG             MsgClass;
  1519.                 UWORD             MsgCode,
  1520.                              MsgQualifier;
  1521.  
  1522.                 while(Message = (struct IntuiMessage *)GetMsg(ReviewWindow -> UserPort))
  1523.                 {
  1524.                     if(Context && Context -> SearchWindow == Message -> IDCMPWindow)
  1525.                     {
  1526.                         MsgClass = NULL;
  1527.  
  1528.                         if(HandleSearchMessage(Context,&Message))
  1529.                         {
  1530.                             BOOLEAN Ok = Context -> Ok;
  1531.  
  1532.                             DeleteSearchContext(Context);
  1533.  
  1534.                             Context = NULL;
  1535.  
  1536.                             if(Ok)
  1537.                             {
  1538.                                 if(SearchInfo)
  1539.                                     DeleteSearchInfo(SearchInfo);
  1540.  
  1541.                                 if(SearchInfo = CreateSearchInfo(SearchBuffer,SearchForward,IgnoreCase,WholeWords))
  1542.                                     ReviewSearch(SearchInfo,SearchBuffer);
  1543.                             }
  1544.                             else
  1545.                             {
  1546.                                 if(SearchInfo)
  1547.                                 {
  1548.                                     DeleteSearchInfo(SearchInfo);
  1549.  
  1550.                                     SearchInfo = NULL;
  1551.                                 }
  1552.                             }
  1553.                         }
  1554.                     }
  1555.                     else
  1556.                     {
  1557.                         MsgClass    = Message -> Class;
  1558.                         MsgCode        = Message -> Code;
  1559.                         MsgQualifier    = Message -> Qualifier;
  1560.                         TagList        = (struct TagItem *)Message -> IAddress;
  1561.  
  1562.                         ReplyMsg((struct Message *)Message);
  1563.                     }
  1564.  
  1565.                     switch(MsgClass)
  1566.                     {
  1567.                         case IDCMP_MENUHELP:
  1568.  
  1569.                             GuideDisplay(CONTEXT_BUFFER_MENU);
  1570.                             break;
  1571.  
  1572.                         case IDCMP_IDCMPUPDATE:
  1573.  
  1574.                             switch(GetTagData(GA_ID,0,TagList))
  1575.                             {
  1576.                                 case GAD_UP:    ReviewUp(1);
  1577.                                         break;
  1578.  
  1579.                                 case GAD_DOWN:    ReviewDown(1);
  1580.                                         break;
  1581.                             }
  1582.  
  1583.                             break;
  1584.  
  1585.                         case IDCMP_GADGETDOWN:
  1586.                         case IDCMP_MOUSEMOVE:
  1587.  
  1588.                             if(ReviewGlobalLines > ReviewLines)
  1589.                             {
  1590.                                 LONG NewTop;
  1591.  
  1592.                                 if(GetAttr(PGA_Top,Scroller,(ULONG *)&NewTop))
  1593.                                     ScrollReview(NewTop);
  1594.                             }
  1595.  
  1596.                             break;
  1597.  
  1598.                         case IDCMP_MENUPICK:
  1599.  
  1600.                             while(MsgCode != MENUNULL)
  1601.                             {
  1602.                                 MenuItem = ItemAddress(ReviewMenuStrip,MsgCode);
  1603.  
  1604.                                 switch((ULONG)GTMENUITEM_USERDATA(MenuItem))
  1605.                                 {
  1606.                                     case MEN_SEARCH:
  1607.  
  1608.                                         if(Context)
  1609.                                             LT_ShowWindow(Context -> SearchHandle,TRUE);
  1610.                                         else
  1611.                                             Context = CreateSearchContext(ReviewWindow,SearchBuffer,&HistoryHook,&SearchForward,&IgnoreCase,&WholeWords);
  1612.  
  1613.                                         break;
  1614.  
  1615.                                     case MEN_REPEAT:
  1616.  
  1617.                                         if(Context)
  1618.                                             LT_ShowWindow(Context -> SearchHandle,TRUE);
  1619.                                         else
  1620.                                         {
  1621.                                             if(SearchInfo)
  1622.                                                 ReviewSearch(SearchInfo,SearchBuffer);
  1623.                                             else
  1624.                                                 Context = CreateSearchContext(ReviewWindow,SearchBuffer,&HistoryHook,&SearchForward,&IgnoreCase,&WholeWords);
  1625.                                         }
  1626.  
  1627.                                         break;
  1628.  
  1629.                                     case MEN_QUITBUF:
  1630.  
  1631.                                         Done = TRUE;
  1632.  
  1633.                                         if(!(SetSignal(0,SIG_KILL) & SIG_KILL))
  1634.                                             Father = NULL;
  1635.  
  1636.                                         break;
  1637.  
  1638.                                     case MEN_CLEARBUF:
  1639.  
  1640.                                         if(Lines)
  1641.                                         {
  1642.                                             if((MsgQualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)) || !Config -> MiscConfig -> ProtectiveMode)
  1643.                                                 FreeBuffer();
  1644.                                             else
  1645.                                             {
  1646.                                                 if(MyEasyRequest(ReviewWindow,LocaleString(MSG_TERMBUFFER_BUFFER_STILL_HOLDS_LINES_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT),Lines))
  1647.                                                     FreeBuffer();
  1648.                                             }
  1649.                                         }
  1650.  
  1651.                                         break;
  1652.                                 }
  1653.  
  1654.                                 MsgCode = MenuItem -> NextSelect;
  1655.                             }
  1656.  
  1657.                             break;
  1658.                     }
  1659.                 }
  1660.             }
  1661.  
  1662.             if(Signals & ReviewQueue -> SigMask)
  1663.             {
  1664.                 struct DataMsg *Msg;
  1665.  
  1666.                 while(Msg = (struct DataMsg *)GetMsgItem(ReviewQueue))
  1667.                 {
  1668.                     switch(Msg -> Type)
  1669.                     {
  1670.                         case DATAMSGTYPE_UPDATEREVIEW:
  1671.  
  1672.                             LocalUpdateReview(Msg -> Size);
  1673.                             break;
  1674.  
  1675.                         case DATAMSGTYPE_MOVEREVIEW:
  1676.  
  1677.                             LocalMoveReview(Msg -> Size);
  1678.                             break;
  1679.                     }
  1680.  
  1681.                     DeleteMsgItem(Msg);
  1682.                 }
  1683.             }
  1684.         }
  1685.         while(!Done);
  1686.  
  1687.         if(Context)
  1688.             DeleteSearchContext(Context);
  1689.  
  1690.         if(SearchInfo)
  1691.             DeleteSearchInfo(SearchInfo);
  1692.  
  1693.         LocalDeleteReview();
  1694.     }
  1695.  
  1696.     Forbid();
  1697.  
  1698.     ReviewProcess = NULL;
  1699.  
  1700.     if(Father)
  1701.         Signal(Father,SIG_HANDSHAKE);
  1702.     else
  1703.         CheckItem(MEN_REVIEW_WINDOW,FALSE);
  1704. }
  1705.  
  1706. VOID __regargs
  1707. UpdateReview(BYTE Force)
  1708. {
  1709.     if(ReviewQueue)
  1710.     {
  1711.         if(SysBase -> ThisTask != (struct Task *)ReviewProcess)
  1712.         {
  1713.             BYTE SigBit;
  1714.  
  1715.             if((SigBit = AllocSignal(-1)) != -1)
  1716.             {
  1717.                 struct DataMsg Msg;
  1718.  
  1719.                 InitMsgItem(&Msg,ReviewClientDestructor);
  1720.  
  1721.                 Msg . Type    = DATAMSGTYPE_UPDATEREVIEW;
  1722.                 Msg . Size    = Force;
  1723.                 Msg . Client    = SysBase -> ThisTask;
  1724.                 Msg . Mask    = 1L << SigBit;
  1725.  
  1726.                 Forbid();
  1727.  
  1728.                 if(ReviewProcess)
  1729.                 {
  1730.                     ClrSignal(Msg . Mask);
  1731.  
  1732.                     PutMsgItem(ReviewQueue,(struct MsgItem *)&Msg);
  1733.  
  1734.                     Wait(Msg . Mask);
  1735.                 }
  1736.  
  1737.                 Permit();
  1738.  
  1739.                 FreeSignal(SigBit);
  1740.             }
  1741.         }
  1742.         else
  1743.             LocalUpdateReview(Force);
  1744.     }
  1745. }
  1746.  
  1747. VOID __regargs
  1748. MoveReview(BYTE Mode)
  1749. {
  1750.     if(ReviewQueue)
  1751.     {
  1752.         if(SysBase -> ThisTask != (struct Task *)ReviewProcess)
  1753.         {
  1754.             BYTE SigBit;
  1755.  
  1756.             if((SigBit = AllocSignal(-1)) != -1)
  1757.             {
  1758.                 struct DataMsg Msg;
  1759.  
  1760.                 InitMsgItem(&Msg,ReviewClientDestructor);
  1761.  
  1762.                 Msg . Type    = DATAMSGTYPE_MOVEREVIEW;
  1763.                 Msg . Size    = Mode;
  1764.                 Msg . Client    = SysBase -> ThisTask;
  1765.                 Msg . Mask    = 1L << SigBit;
  1766.  
  1767.                 Forbid();
  1768.  
  1769.                 if(ReviewProcess)
  1770.                 {
  1771.                     ClrSignal(Msg . Mask);
  1772.  
  1773.                     PutMsgItem(ReviewQueue,(struct MsgItem *)&Msg);
  1774.  
  1775.                     Wait(Msg . Mask);
  1776.                 }
  1777.  
  1778.                 Permit();
  1779.  
  1780.                 FreeSignal(SigBit);
  1781.             }
  1782.         }
  1783.         else
  1784.             LocalMoveReview(Mode);
  1785.     }
  1786. }
  1787.  
  1788. VOID
  1789. DeleteReview()
  1790. {
  1791.     CheckItem(MEN_REVIEW_WINDOW,FALSE);
  1792.  
  1793.     Forbid();
  1794.  
  1795.     if(ReviewProcess)
  1796.     {
  1797.         ClrSignal(SIG_HANDSHAKE);
  1798.  
  1799.         Signal(ReviewProcess,SIG_KILL);
  1800.  
  1801.         Wait(SIG_HANDSHAKE);
  1802.     }
  1803.  
  1804.     Permit();
  1805. }
  1806.  
  1807. BYTE
  1808. CreateReview()
  1809. {
  1810.     if(ReviewProcess)
  1811.         return(TRUE);
  1812.     else
  1813.     {
  1814.         BYTE Result = FALSE;
  1815.  
  1816.         Forbid();
  1817.  
  1818.         if(CreateNewProcTags(
  1819.             NP_Entry,    ReviewProcessEntry,
  1820.             NP_Name,    "term Review Process",
  1821.             NP_Priority,    SysBase -> ThisTask -> tc_Node . ln_Pri,
  1822.             NP_StackSize,    4000,
  1823.             NP_WindowPtr,    -1,
  1824.         TAG_END))
  1825.         {
  1826.             ClrSignal(SIG_HANDSHAKE);
  1827.  
  1828.             Wait(SIG_HANDSHAKE);
  1829.  
  1830.             if(ReviewProcess)
  1831.             {
  1832.                 CheckItem(MEN_REVIEW_WINDOW,TRUE);
  1833.  
  1834.                 Result = TRUE;
  1835.             }
  1836.         }
  1837.  
  1838.         Permit();
  1839.  
  1840.         return(Result);
  1841.     }
  1842. }
  1843.